﻿using Qiniu.IO;
using Qiniu.IO.Resumable;
using Qiniu.RPC;
using Qiniu.RS;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Helpers
{
    /// <summary>
    /// 对七牛云api的封装的帮助类
    /// </summary>
    public class QiniuHelper
    {
        public static void Init()
        {
            Qiniu.Conf.Config.Init();
        }
        /// <summary>
        /// 简单上传，传送小文件比较快
        /// </summary>
        /// <param name="bucket">设置上传的空间</param>
        /// <param name="key">设置上传的文件的key值</param>
        /// <param name="filePath">上传文件的路径</param>
        /// <param name="CallBackUrl">回调路径</param>
        /// <param name="CallBackBody">回调内容</param>
        public static bool Upload(String bucket, String key, String filePath, string CallBackUrl = null, string CallBackBody = null)
        {
            IOClient target = new IOClient();
            PutExtra extra = new PutExtra();
            //普通上传,只需要设置上传的空间名就可以了,第二个参数可以设定token过期时间
            PutPolicy put = new PutPolicy(bucket, 3600);
            put.CallBackBody = CallBackUrl;
            put.CallBackUrl = CallBackUrl;
            //调用Token()方法生成上传的Token
            string upToken = put.Token();
            //调用PutFile()方法上传
            PutRet ret = target.PutFile(upToken, key, filePath, extra);
            //打印出相应的信息
            return ret.OK;
        }

        /// <summary>
        /// 断点续上传，在网络条件很一般的情况下也能有出色的上传速度，而且对大文件的传输非常友好
        /// </summary>
        /// <param name="bucket"></param>
        /// <param name="key"></param>
        /// <param name="filePath"></param>
        public static bool BCUpload(String bucket, String key, String filePath, string CallBackUrl = null, string CallBackBody = null)
        {
            PutPolicy put = new PutPolicy(bucket, 3600);
            //设置callbackUrl以及callbackBody,七牛将文件名和文件大小回调给业务服务器
            put.CallBackBody = CallBackUrl;
            put.CallBackUrl = CallBackUrl;
            string upToken = put.Token();
            Settings setting = new Settings();
            ResumablePutExtra extra = new ResumablePutExtra();
            extra.MimeType = "application/octet-stream";
            extra.Notify += new EventHandler<PutNotifyEvent>(extra_Notify);
            extra.NotifyErr += new EventHandler<PutNotifyErrorEvent>(extra_NotifyErr);
            ResumablePut client = new ResumablePut(setting, extra);
            CallRet ret = client.PutFile(upToken, filePath, key);
            return ret.OK;


        }

        /// <summary>
        /// 上传&预转持续化
        /// </summary>
        /// <param name="bucket"></param>
        /// <param name="key"></param>
        /// <param name="filePath"></param>
        /// <param name="CallBackUrl"></param>
        /// <param name="CallBackBody"></param>
        public static void UploadAndChange(String bucket, String key, String filePath ,string CallBackUrl = null, string CallBackBody = null)
        {
            IOClient target = new IOClient();
            PutExtra extra = new PutExtra();
            //设置转码操作参数
            String fops = "avthumb/mp4/s/640x360b/1.25m";
            //设置转码的队列
            String pipeline = "yourpipelinename";
            //可以对转码后的文件进行使用saveas参数自定义命名，当然也可以不指定文件会默认命名并保存在当前空间。
            String urlbase64 = Qiniu.Util.Base64URLSafe.Encode("目标Bucket_Name:自定义文件key");
            String pfops = fops + "|saveas/" + urlbase64;
            //普通上传,只需要设置上传的空间名就可以了,第二个参数可以设定token过期时间
            PutPolicy put = new PutPolicy(bucket, 3600);
            //设置PersistentOps以及PersistentPipeline
            put.PersistentOps = fops;
            put.PersistentPipeline = pipeline;
            //调用Token()方法生成上传的Token
            string upToken = put.Token();
            //上传文件的路径
            PutRet ret = target.PutFile(upToken, key, filePath, extra);
            //打印出相应的信息
            Console.WriteLine(ret.Response.ToString());
            Console.WriteLine(ret.key);
            Console.ReadLine();
        }
        /// <summary>
        /// 调用MakeRequest方法生成私有下载链接
        /// </summary>
        /// <param name="baseUrl">构造私有空间的需要生成的下载的链接</param>
        public static string MakeRequest(string baseUrl)
        {
            return  GetPolicy.MakeRequest(baseUrl);
        }

        /// <summary>
        /// 获取文件信息
        /// </summary>
        /// <param name="bucket"></param>
        /// <param name="key">区分大小写</param>
        public static void GetFileInfo(String bucket, String key)
        {
            //实例化一个RSClient对象，用于操作BucketManager里面的方法
            RSClient client = new RSClient();
            //调用Stat方法获取文件的信息
            Entry entry = client.Stat(new EntryPath(bucket, key));
            if (entry.OK)
            {
                //打印文件的hash、fsize等信息
                Debug.WriteLine("Hash: " + entry.Hash);
                Debug.WriteLine("Fsize: " + entry.Fsize);
                Debug.WriteLine("PutTime: " + entry.PutTime);
                Debug.WriteLine("MimeType: " + entry.MimeType);
            }
            else
            {
                Debug.WriteLine("Failed to Stat");
            }

        }

        /// <summary>
        /// 移动
        /// </summary>
        /// <param name="bucketSrc"></param>
        /// <param name="keySrc"></param>
        /// <param name="bucketDest"></param>
        /// <param name="keyDest"></param>
        public static void Move(string bucketSrc, string keySrc, string bucketDest, string keyDest)
        {

            //实例化一个RSClient对象，用于操作BucketManager里面的方法
            RSClient client = new RSClient();
            new EntryPathPair(bucketSrc, keySrc, bucketDest, keyDest);
            CallRet ret = client.Move(new EntryPathPair(bucketSrc, keySrc, bucketDest, keyDest));
            if (ret.OK)
            {
                Console.WriteLine("Move OK");
            }
            else
            {
                Console.WriteLine("Failed to Move");
            }
        }

        /// <summary>
        /// 复制
        /// </summary>
        /// <param name="bucketSrc"></param>
        /// <param name="keySrc"></param>
        /// <param name="bucketDest"></param>
        /// <param name="keyDest"></param>
        public static void Copy(string bucketSrc, string keySrc, string bucketDest, string keyDest)
        {
            //实例化一个RSClient对象，用于操作BucketManager里面的方法
            RSClient client = new RSClient();
            CallRet ret = client.Copy(new EntryPathPair(bucketSrc, keySrc, bucketDest, keyDest));
            if (ret.OK)
            {
                Console.WriteLine("Copy OK");
            }
            else
            {
                Console.WriteLine("Failed to Copy");
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="bucket"></param>
        /// <param name="key"></param>
        public static void Delete(string bucket, string key)
        {
            //实例化一个RSClient对象，用于操作BucketManager里面的方法
            RSClient client = new RSClient();
            CallRet ret = client.Delete(new EntryPath(bucket, key));
            if (ret.OK)
            {
                Console.WriteLine("Delete OK");
            }
            else
            {
                Console.WriteLine("Failed to delete");
            }
        }
        /// <summary>
        /// Get方式获取文件
        /// </summary>
        /// <param name="domain">文件域</param>
        /// <param name="key">文件Key</param>
        public static void GetFile(string domain, string key)
        {
            System.Diagnostics.Process.Start("http://" + domain + "/" + key);
        }
        private static void extra_Notify(object sender, PutNotifyEvent e)
        {
            Debug.WriteLine(e.BlkIdx.ToString() + "----" + e.BlkSize.ToString());
        }
        private static void extra_NotifyErr(object sender, PutNotifyErrorEvent e)
        {
            e.BlkIdx.ToString();
            e.BlkSize.ToString();
        }
    }
}
